package com.cirnoworks.guice.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.quartz.Calendar;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.ListenerManager;
import org.quartz.Scheduler;
import org.quartz.SchedulerContext;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SchedulerMetaData;
import org.quartz.Trigger;
import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerKey;
import org.quartz.UnableToInterruptJobException;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.spi.JobFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cirnoworks.guice.LifeCycleSupport;

@Singleton
public class CirnoSchedulerImpl extends LifeCycleSupport implements Scheduler {

	private static final Logger LOG = LoggerFactory
			.getLogger(CirnoSchedulerImpl.class);

	private Scheduler scheduler;

	@Inject
	public CirnoSchedulerImpl(final JobFactory jobFactory,
			final SchedulerFactory schedulerFactory) throws SchedulerException {
		scheduler = schedulerFactory.getScheduler();
		scheduler.setJobFactory(jobFactory);
	}

	public void startup() {
		try {
			LOG.info("Scheduler started...");
			start();
		} catch (SchedulerException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#shutdown()
	 */
	public void shutdown() {
		try {
			LOG.info("Scheduler shutdown...");
			scheduler.shutdown();
		} catch (SchedulerException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getSchedulerName()
	 */
	public String getSchedulerName() throws SchedulerException {
		return scheduler.getSchedulerName();
	}

	/**
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getSchedulerInstanceId()
	 */
	public String getSchedulerInstanceId() throws SchedulerException {
		return scheduler.getSchedulerInstanceId();
	}

	/**
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getContext()
	 */
	public SchedulerContext getContext() throws SchedulerException {
		return scheduler.getContext();
	}

	/**
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#start()
	 */
	public void start() throws SchedulerException {
		scheduler.start();
	}

	/**
	 * @param seconds
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#startDelayed(int)
	 */
	public void startDelayed(int seconds) throws SchedulerException {
		scheduler.startDelayed(seconds);
	}

	/**
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#isStarted()
	 */
	public boolean isStarted() throws SchedulerException {
		return scheduler.isStarted();
	}

	/**
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#standby()
	 */
	public void standby() throws SchedulerException {
		scheduler.standby();
	}

	/**
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#isInStandbyMode()
	 */
	public boolean isInStandbyMode() throws SchedulerException {
		return scheduler.isInStandbyMode();
	}

	/**
	 * @param waitForJobsToComplete
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#shutdown(boolean)
	 */
	public void shutdown(boolean waitForJobsToComplete)
			throws SchedulerException {
		scheduler.shutdown(waitForJobsToComplete);
	}

	/**
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#isShutdown()
	 */
	public boolean isShutdown() throws SchedulerException {
		return scheduler.isShutdown();
	}

	/**
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getMetaData()
	 */
	public SchedulerMetaData getMetaData() throws SchedulerException {
		return scheduler.getMetaData();
	}

	/**
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getCurrentlyExecutingJobs()
	 */
	public List<JobExecutionContext> getCurrentlyExecutingJobs()
			throws SchedulerException {
		return scheduler.getCurrentlyExecutingJobs();
	}

	/**
	 * @param factory
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#setJobFactory(org.quartz.spi.JobFactory)
	 */
	public void setJobFactory(JobFactory factory) throws SchedulerException {
		scheduler.setJobFactory(factory);
	}

	/**
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getListenerManager()
	 */
	public ListenerManager getListenerManager() throws SchedulerException {
		return scheduler.getListenerManager();
	}

	/**
	 * @param jobDetail
	 * @param trigger
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#scheduleJob(org.quartz.JobDetail,
	 *      org.quartz.Trigger)
	 */
	public Date scheduleJob(JobDetail jobDetail, Trigger trigger)
			throws SchedulerException {
		return scheduler.scheduleJob(jobDetail, trigger);
	}

	/**
	 * @param trigger
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#scheduleJob(org.quartz.Trigger)
	 */
	public Date scheduleJob(Trigger trigger) throws SchedulerException {
		return scheduler.scheduleJob(trigger);
	}

	/**
	 * @param triggersAndJobs
	 * @param replace
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#scheduleJobs(java.util.Map, boolean)
	 */
	public void scheduleJobs(Map<JobDetail, List<Trigger>> triggersAndJobs,
			boolean replace) throws SchedulerException {
		scheduler.scheduleJobs(triggersAndJobs, replace);
	}

	/**
	 * @param triggerKey
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#unscheduleJob(org.quartz.TriggerKey)
	 */
	public boolean unscheduleJob(TriggerKey triggerKey)
			throws SchedulerException {
		return scheduler.unscheduleJob(triggerKey);
	}

	/**
	 * @param triggerKeys
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#unscheduleJobs(java.util.List)
	 */
	public boolean unscheduleJobs(List<TriggerKey> triggerKeys)
			throws SchedulerException {
		return scheduler.unscheduleJobs(triggerKeys);
	}

	/**
	 * @param triggerKey
	 * @param newTrigger
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#rescheduleJob(org.quartz.TriggerKey,
	 *      org.quartz.Trigger)
	 */
	public Date rescheduleJob(TriggerKey triggerKey, Trigger newTrigger)
			throws SchedulerException {
		return scheduler.rescheduleJob(triggerKey, newTrigger);
	}

	/**
	 * @param jobDetail
	 * @param replace
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#addJob(org.quartz.JobDetail, boolean)
	 */
	public void addJob(JobDetail jobDetail, boolean replace)
			throws SchedulerException {
		scheduler.addJob(jobDetail, replace);
	}

	/**
	 * @param jobKey
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#deleteJob(org.quartz.JobKey)
	 */
	public boolean deleteJob(JobKey jobKey) throws SchedulerException {
		return scheduler.deleteJob(jobKey);
	}

	/**
	 * @param jobKeys
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#deleteJobs(java.util.List)
	 */
	public boolean deleteJobs(List<JobKey> jobKeys) throws SchedulerException {
		return scheduler.deleteJobs(jobKeys);
	}

	/**
	 * @param jobKey
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#triggerJob(org.quartz.JobKey)
	 */
	public void triggerJob(JobKey jobKey) throws SchedulerException {
		scheduler.triggerJob(jobKey);
	}

	/**
	 * @param jobKey
	 * @param data
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#triggerJob(org.quartz.JobKey,
	 *      org.quartz.JobDataMap)
	 */
	public void triggerJob(JobKey jobKey, JobDataMap data)
			throws SchedulerException {
		scheduler.triggerJob(jobKey, data);
	}

	/**
	 * @param jobKey
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#pauseJob(org.quartz.JobKey)
	 */
	public void pauseJob(JobKey jobKey) throws SchedulerException {
		scheduler.pauseJob(jobKey);
	}

	/**
	 * @param matcher
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#pauseJobs(org.quartz.impl.matchers.GroupMatcher)
	 */
	public void pauseJobs(GroupMatcher<JobKey> matcher)
			throws SchedulerException {
		scheduler.pauseJobs(matcher);
	}

	/**
	 * @param triggerKey
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#pauseTrigger(org.quartz.TriggerKey)
	 */
	public void pauseTrigger(TriggerKey triggerKey) throws SchedulerException {
		scheduler.pauseTrigger(triggerKey);
	}

	/**
	 * @param matcher
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#pauseTriggers(org.quartz.impl.matchers.GroupMatcher)
	 */
	public void pauseTriggers(GroupMatcher<TriggerKey> matcher)
			throws SchedulerException {
		scheduler.pauseTriggers(matcher);
	}

	/**
	 * @param jobKey
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#resumeJob(org.quartz.JobKey)
	 */
	public void resumeJob(JobKey jobKey) throws SchedulerException {
		scheduler.resumeJob(jobKey);
	}

	/**
	 * @param matcher
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#resumeJobs(org.quartz.impl.matchers.GroupMatcher)
	 */
	public void resumeJobs(GroupMatcher<JobKey> matcher)
			throws SchedulerException {
		scheduler.resumeJobs(matcher);
	}

	/**
	 * @param triggerKey
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#resumeTrigger(org.quartz.TriggerKey)
	 */
	public void resumeTrigger(TriggerKey triggerKey) throws SchedulerException {
		scheduler.resumeTrigger(triggerKey);
	}

	/**
	 * @param matcher
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#resumeTriggers(org.quartz.impl.matchers.GroupMatcher)
	 */
	public void resumeTriggers(GroupMatcher<TriggerKey> matcher)
			throws SchedulerException {
		scheduler.resumeTriggers(matcher);
	}

	/**
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#pauseAll()
	 */
	public void pauseAll() throws SchedulerException {
		scheduler.pauseAll();
	}

	/**
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#resumeAll()
	 */
	public void resumeAll() throws SchedulerException {
		scheduler.resumeAll();
	}

	/**
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getJobGroupNames()
	 */
	public List<String> getJobGroupNames() throws SchedulerException {
		return scheduler.getJobGroupNames();
	}

	/**
	 * @param matcher
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getJobKeys(org.quartz.impl.matchers.GroupMatcher)
	 */
	public Set<JobKey> getJobKeys(GroupMatcher<JobKey> matcher)
			throws SchedulerException {
		return scheduler.getJobKeys(matcher);
	}

	/**
	 * @param jobKey
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getTriggersOfJob(org.quartz.JobKey)
	 */
	public List<? extends Trigger> getTriggersOfJob(JobKey jobKey)
			throws SchedulerException {
		return scheduler.getTriggersOfJob(jobKey);
	}

	/**
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getTriggerGroupNames()
	 */
	public List<String> getTriggerGroupNames() throws SchedulerException {
		return scheduler.getTriggerGroupNames();
	}

	/**
	 * @param matcher
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getTriggerKeys(org.quartz.impl.matchers.GroupMatcher)
	 */
	public Set<TriggerKey> getTriggerKeys(GroupMatcher<TriggerKey> matcher)
			throws SchedulerException {
		return scheduler.getTriggerKeys(matcher);
	}

	/**
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getPausedTriggerGroups()
	 */
	public Set<String> getPausedTriggerGroups() throws SchedulerException {
		return scheduler.getPausedTriggerGroups();
	}

	/**
	 * @param jobKey
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getJobDetail(org.quartz.JobKey)
	 */
	public JobDetail getJobDetail(JobKey jobKey) throws SchedulerException {
		return scheduler.getJobDetail(jobKey);
	}

	/**
	 * @param triggerKey
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getTrigger(org.quartz.TriggerKey)
	 */
	public Trigger getTrigger(TriggerKey triggerKey) throws SchedulerException {
		return scheduler.getTrigger(triggerKey);
	}

	/**
	 * @param triggerKey
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getTriggerState(org.quartz.TriggerKey)
	 */
	public TriggerState getTriggerState(TriggerKey triggerKey)
			throws SchedulerException {
		return scheduler.getTriggerState(triggerKey);
	}

	/**
	 * @param calName
	 * @param calendar
	 * @param replace
	 * @param updateTriggers
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#addCalendar(java.lang.String,
	 *      org.quartz.Calendar, boolean, boolean)
	 */
	public void addCalendar(String calName, Calendar calendar, boolean replace,
			boolean updateTriggers) throws SchedulerException {
		scheduler.addCalendar(calName, calendar, replace, updateTriggers);
	}

	/**
	 * @param calName
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#deleteCalendar(java.lang.String)
	 */
	public boolean deleteCalendar(String calName) throws SchedulerException {
		return scheduler.deleteCalendar(calName);
	}

	/**
	 * @param calName
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getCalendar(java.lang.String)
	 */
	public Calendar getCalendar(String calName) throws SchedulerException {
		return scheduler.getCalendar(calName);
	}

	/**
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#getCalendarNames()
	 */
	public List<String> getCalendarNames() throws SchedulerException {
		return scheduler.getCalendarNames();
	}

	/**
	 * @param jobKey
	 * @return
	 * @throws UnableToInterruptJobException
	 * @see org.quartz.Scheduler#interrupt(org.quartz.JobKey)
	 */
	public boolean interrupt(JobKey jobKey)
			throws UnableToInterruptJobException {
		return scheduler.interrupt(jobKey);
	}

	/**
	 * @param fireInstanceId
	 * @return
	 * @throws UnableToInterruptJobException
	 * @see org.quartz.Scheduler#interrupt(java.lang.String)
	 */
	public boolean interrupt(String fireInstanceId)
			throws UnableToInterruptJobException {
		return scheduler.interrupt(fireInstanceId);
	}

	/**
	 * @param jobKey
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#checkExists(org.quartz.JobKey)
	 */
	public boolean checkExists(JobKey jobKey) throws SchedulerException {
		return scheduler.checkExists(jobKey);
	}

	/**
	 * @param triggerKey
	 * @return
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#checkExists(org.quartz.TriggerKey)
	 */
	public boolean checkExists(TriggerKey triggerKey) throws SchedulerException {
		return scheduler.checkExists(triggerKey);
	}

	/**
	 * @throws SchedulerException
	 * @see org.quartz.Scheduler#clear()
	 */
	public void clear() throws SchedulerException {
		scheduler.clear();
	}

}
